package com.gitee.wsl.common.ui.ext.color

import androidx.compose.ui.graphics.Color
import com.gitee.wsl.ext.number.pow
import com.gitee.wsl.mathematics.interpolator.ext.ratio


operator fun Color.plus(other:Color) =
    Color.rgb(r+other.r,g+other.g,b+other.b,(alpha+other.alpha).ratio)

operator fun Color.minus(other:Color) =
    Color.rgb(r-other.r,g-other.g,b-other.b,(alpha-other.alpha).ratio)

 fun Color.scale(s:Float) =
    Color.rgb((r*s).toInt(),(g*s).toInt(),(b*s).toInt(),(alpha*s).ratio)


/**
 * Modify a value from the gamma space to the linear space.
 * @param value - The value in gamma space
 * @returns The value in linear space
 */
fun gammaToLinearSpace(value: Float): Float {
    // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_framebuffer_sRGB.txt
    // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_sRGB_decode.txt

    return if (value <= 0.0) 0.0f
    else if (value <= 0.04045) value / 12.92f
    else if (value < 1.0) ((value + 0.055f) / 1.055f).pow( 2.4f)
    else value.pow(2.4f)
}

/**
 * Modify a value from the linear space to the gamma space.
 * @param value - The value in linear space
 * @returns The value in gamma space
 */
fun linearToGammaSpace(value: Float): Float {
    // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_framebuffer_sRGB.txt
    // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_sRGB_decode.txt

    if (value <= 0.0f) return 0.0f
    else if (value < 0.0031308) return 12.92f * value
    else if (value < 1.0) return 1.055f * value.pow (0.41666f) - 0.055f
    else return value .pow (0.41666f)
}

/**
 * Modify components (r, g, b) of this color from gamma space to linear space.
 * @param out - The color in linear space
 * @returns The color in linear space
 */
fun Color.gammaToLinear(): Color {
    val _r = gammaToLinearSpace(r.toFloat()).toInt()
    val _g = gammaToLinearSpace(g.toFloat()).toInt()
    val _b = gammaToLinearSpace(b.toFloat()).toInt()
    return Color(_r,_g,_b)
}

/**
 * Modify components (r, g, b) of this color from linear space to gamma space.
 * @param out - The color in gamma space
 * @returns The color in gamma space
 */
fun Color.linearToGamma(): Color {
    val _r = linearToGammaSpace(r.toFloat()).toInt()
    val _g = linearToGammaSpace(g.toFloat()).toInt()
    val _b = linearToGammaSpace(b.toFloat()).toInt()
    return Color(_r,_g,_b)
}